/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2020年9月16日
 */
package com.massyframework.beanskin.web;

import javax.servlet.ServletContext;

import com.massyframework.beanskin.Module;

/**
 * {@link ModularServletContext} 为装配件提供ServletContext initParameter和attribute的隔离能力。<br>
 *
 * 如果在调用{@link #setAttribute(String, Object)}和{@link #setInitParameter(String, String)}方法时，默认情况下，
 * {@link ModularServletContext}会独立存放属性和初始化参数，除非属性和初始化参数具有{@link #ROOT_PREFIX}前缀，{@link ModularServletContext}
 * 才会去掉前缀将属性或初始化参数保存到原始的{@link ServletContext}中。
 * 初始化参数和属性的读取方法和设置方法类似，如果属性名或者初始化参数名以{@link #ROOT_PREFIX}开头，则直接从原始的{@link ServletContext}中读取，
 * 否则先尝试从独立存放区获取属性或者初始化参数，如果未独立存放该属性或者初始化参数，再从原始的{@link ServletContext}中获取相应的属性和初始化参数。
 * 
 * @author huangkh 
 */
public interface ModularServletContext extends ServletContext {

	/**
	 * 带本前缀的属性，在原生ServletContext中查找或者更新去掉前缀的属性
	 */
	static final String ROOT_PREFIX = "$.";
	/**
	 * 带本前缀的属性，仅允许在本地查找或者更新去掉前缀的属性
	 */
	static final String LOCAL_PREFIX = "#.";

    /**
     * 获取关联的模块
     * @return {@link Module}
     */
    Module<?> getAssociatedModule();
    
    /**
     * 按{@code name}获取属性值
     * <p>
     * 首先从模块ServletContext隔离的属性集合中查找属性，如果未找到，<br>
     * 则根据{@code useOriginal}决定是否从原始ServletContext中尝试获取属性集。
     * @param name {@link String},属性名
     * @param useOriginal {@link boolean},如果属性不存在时，是否从原始ServletContext中获取属性
     * @return {@link Object}
     */
    Object getAttribute(String name, boolean useOriginal);
    
    /**
     * 清除隔离存储的初始化参数和属性
     * <br>本方法在装配件卸载时调用
     */
    void clean();
}
